#include "types.h"
#include "core.h"
#include <iostream>

using namespace std;

int
main ()
{
  cout << "~~~ REDLisp Test 3 ~~~\n";
    cout << "\n*** PARSER TEST 1 ***\n";
  list<string> tokens = tokenize ("hello world");
  cout << "tokenize \"hello world\" (size: " << tokens.size () << "): ";
  for (list<string>::iterator i = tokens.begin (); i != tokens.end (); i++)
    cout << *i << "|";
  cout << "\n*** PARSER TEST 2 ***\n";
  tokens = tokenize ("hello  \t  world");
  cout << "tokenize \"hello  \t  world\" (size: " << tokens.size () << "): ";
  for (list<string>::iterator i = tokens.begin (); i != tokens.end (); i++)
    cout << *i << "|";

  tokens = tokenize ("  ( hello    world  )  ");
  cout << "tokenize \"  ( hello    world  )  \" (size: "
       << tokens.size () << "): ";
  for (list<string>::iterator i = tokens.begin (); i != tokens.end (); i++)
    cout << *i << "|";

  cout << "\n*** PARSER TEST 3 ***\n";
  cout << "type of parseAtom \"atom\": "
       << parseAtom ("atom")->type ()
       << "\ntype of parseAtom \"3\": "
       << parseAtom ("3")->type ()
       << "\ntype of parseAtom \"25.23\": "
       << parseAtom ("25.23")->type ()
       << "\ntype of parseAtom \"\"Hello world!\"\": "
       << parseAtom ("\"Hello world!\"")->type ();

  cout << "\n*** PARSER TEST 4 ***\n";
  // ToDo: Add tests for parseList
  cout << "parseList \"(function)\": "
       << parseList ("(function)")->toString ()
       << "\nparseList \"(function arg1 arg2)\": "
       << parseList ("(function arg1 arg2)")->toString ();
  Object* x = parseList ("(function \"Hello\")");
  cout << "\nparseList \"(function \"Hello\")\": "
       << x->toString () << endl;
  if (x->type () == "List")
    {
      List* blah = (List*)x;
      cout << "blah.size: " << blah->size ()
	   << "\nfirst item (" << (*blah)[0]->type () << "): "
	   << (*blah)[0]->toString ()
	   << "\nsecond item (" << (*blah)[1]->type () << "): "
	   << (*blah)[1]->toString () << endl;
    }
  x = parseList ("(function \"Hello World\"");
  cout << "\nparseList \"(function \"Hello World\")\": "
       << x->toString () << endl;
  if (x->type () == "List")
    {
      List* blah = (List*)x;
      cout << "blah.size: " << blah->size ()
	   << "\nfirst item (" << (*blah)[0]->type () << "): "
	   << (*blah)[0]->toString ()
	   << "\nsecond item (" << (*blah)[1]->type () << "): "
	   << (*blah)[1]->toString () << endl;
    }
  x = parseList ("(* (+ 2 3) 4)");
  cout << "parseList \"(* (+ 2 3) 4)\": " << x->toString () << endl;
  x = parseList ("(print \"REDLisp has a fixed tokenizer after a year, awesome no?\")");
  cout << "parseList \"(print \"REDLisp has a fixed tokenizer after a year, awesome no?\")\": "
       << x->toString () << endl;
  if (x->type () == "List")
    {
      List* blah = (List*)x;
      cout << "blah.size: " << blah->size ()
	   << "\nfirst item (" << (*blah)[0]->type () << "): "
	   << (*blah)[0]->toString ()
	   << "\nsecond item (" << (*blah)[1]->type () << "): "
	   << (*blah)[1]->toString () << endl;
    }

  cout << "\n*** PARSER TEST 5 ***\n";
  // ToDo: Add tests for parse
  cout << endl;
  return 0;
}
